/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package com.googlecode.ivybeans.module.nodes;

import com.googlecode.ivybeans.facade.ArtifactInfo;
import com.googlecode.ivybeans.facade.IvyLibrary;
import com.googlecode.ivybeans.module.IvyLibraryController;
import com.googlecode.ivybeans.module.resources.ResourcesAccess;
import java.awt.Image;
import java.beans.BeanInfo;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collection;
import javax.swing.Icon;
import javax.swing.UIManager;
import org.netbeans.api.project.Project;
import org.openide.filesystems.Repository;
import org.openide.loaders.DataFolder;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;
import org.openide.util.Utilities;

/**
 * 
 * @author lforet
 */
public class LibrariesNode extends AbstractNode {

    private final static String NODE_NAME = NbBundle.getMessage(ResourcesAccess.class, "CTL_LibrariesNode");
    private static final String ICON_KEY_UIMANAGER = "Tree.closedIcon"; // NOI18N
    private static final String OPENED_ICON_KEY_UIMANAGER = "Tree.openIcon"; // NOI18N
    private static final String ICON_KEY_UIMANAGER_NB = "Nb.Explorer.Folder.icon"; // NOI18N
    private static final String OPENED_ICON_KEY_UIMANAGER_NB = "Nb.Explorer.Folder.openedIcon"; // NOI18N
    private static final Image ICON_BADGE = Utilities.loadImage("org/netbeans/modules/java/j2seproject/ui/resources/libraries-badge.png");    //NOI18N
    private static Image folderIconCache;
    private static Image openedFolderIconCache;
    static final RequestProcessor rp = new RequestProcessor();

    public LibrariesNode(Project project) {
        super(new LibrariesChildren(project));
    }

    @Override
    public String getDisplayName() {
        return NODE_NAME;
    }

    @Override
    public String getName() {
        return NODE_NAME;
    }

    @Override
    public Image getIcon(int type) {
        return computeIcon(false, type);
    }

    @Override
    public Image getOpenedIcon(int type) {
        return computeIcon(true, type);
    }

    @Override
    public boolean canCopy() {
        return false;
    }

    /**
     * Returns Icon of folder on active platform
     * @param opened should the icon represent opened folder
     * @return the folder icon
     */
    static synchronized Image getFolderIcon(boolean opened) {
        if (opened) {
            if (openedFolderIconCache == null) {
                openedFolderIconCache = getTreeFolderIcon(opened);
            }
            return openedFolderIconCache;
        } else {
            if (folderIconCache == null) {
                folderIconCache = getTreeFolderIcon(opened);
            }
            return folderIconCache;
        }
    }

    private Image computeIcon(boolean opened, int type) {
        Image image = getFolderIcon(opened);
        image = Utilities.mergeImages(image, ICON_BADGE, 7, 7);
        return image;
    }

    /**
     * Returns default folder icon as {@link java.awt.Image}. Never returns
     * <code>null</code>.
     *
     * @param opened wheter closed or opened icon should be returned.
     */
    private static Image getTreeFolderIcon(boolean opened) {
        Image base = null;
        Icon baseIcon = UIManager.getIcon(opened ? OPENED_ICON_KEY_UIMANAGER : ICON_KEY_UIMANAGER); // #70263
        if (baseIcon != null) {
            base = Utilities.icon2Image(baseIcon);
        } else {
            base = (Image) UIManager.get(opened ? OPENED_ICON_KEY_UIMANAGER_NB : ICON_KEY_UIMANAGER_NB); // #70263
            if (base == null) { // fallback to our owns                
                final Node n = DataFolder.findFolder(Repository.getDefault().getDefaultFileSystem().getRoot()).getNodeDelegate();
                base = opened ? n.getOpenedIcon(BeanInfo.ICON_COLOR_16x16) : n.getIcon(BeanInfo.ICON_COLOR_16x16);                                 
            }
        }
        assert base != null;
        return base;
    }

    private static class LibrariesChildren extends Children.Keys<ArtifactInfo> implements PropertyChangeListener {

        private Project project;

        public LibrariesChildren(Project project) {
            this.project = project;
            IvyLibraryController ivyLibraryController = (IvyLibraryController) project.getLookup().lookup(IvyLibraryController.class);
            ivyLibraryController.addPropertyChangeListener(this);
            setKeys();
        }

        @Override
        protected Node[] createNodes(ArtifactInfo key) {
            return new Node[]{new ArtifactNode(key)};
        }

        public void propertyChange(PropertyChangeEvent evt) {
            if (IvyLibraryController.DESCRIPTOR_CHANGE.equals(evt.getPropertyName())) {
                setKeys();
            }
        }

        private void setKeys() {
            IvyLibrary ivyLibrary = (IvyLibrary) project.getLookup().lookup(IvyLibrary.class);
            Collection<ArtifactInfo> artifacts = ivyLibrary.getResolvedIvyLibrary().getArtifacts();
            setKeys(artifacts);
        }
    }
}
